#pragma once

#include "has_type_test.h"
#include <boost/preprocessor.hpp>
#include "nef_common.h"

#define PP_TYPE_TEST(z, C, txt) DECLARE_TYPE_TEST(txt ## C)

BOOST_PP_REPEAT(MAX_IMPORTS, PP_TYPE_TEST, import)
BOOST_PP_REPEAT(MAX_EXPORTS, PP_TYPE_TEST, export)

#define PP_DECLARE_RESOLVE(z, n, rtype) \
	namespace nef {\
	template<typename Trait, typename T, bool val> \
struct resolve_ ## rtype ## _ ## n ## _t \
{ \
	template<typename CT> static void Resolve(CT &c, const T &val) { } \
}; \
	\
	template<typename Trait, typename T> \
struct resolve_ ## rtype ## _ ## n ## _t<Trait, T, true> \
{ \
	template<typename CT> \
	static void Resolve(CT &c, T &val) \
{ \
	resolve_ ## rtype<T, typename Trait::rtype ## n>(c, val); \
} \
}; \
	\
	template<typename Trait, typename T = Trait> \
struct resolve_ ## rtype ## _ ## n \
	: resolve_ ## rtype ## _ ## n ## _t<Trait, T, has_ ## rtype ## n ## _test<Trait>::value> \
{};  }

#define PP_RESOLVE(z, C, rtype) resolve_ ## rtype ## _ ## C<T>::Resolve(cat, val);
#define PP_RESOLVE_T(z, C, rtype) resolve_ ## rtype ## _ ## C<nef_traits<T>, T>::Resolve(cat, val);